package com.wsoft.dc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.cmd.DcConfigService;
import com.wsoft.dc.constant.ConfigConstant;
import com.wsoft.dc.entity.DcConfigEntity;
import com.wsoft.dc.entity.DcConfigEntityEntity;
import com.wsoft.dc.enums.ConfigEntityTypeEnum;
import com.wsoft.dc.manager.DcConfigEntityManager;
import com.wsoft.dc.manager.DcConfigManager;
import com.wsoft.dc.mapper.DcConfigMapper;
import com.wsoft.dc.query.config.*;
import com.wsoft.dc.service.IDcConfigService;
import com.wsoft.entity.BaseConfigVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 待办中心配置 服务实现类
 * </p>
 *
 * @author Z001
 * @since 2024年12月17日 16:18:10
 */
@Service
@Slf4j
public class DcConfigServiceImpl extends ServiceImpl<DcConfigMapper, DcConfigEntity> implements IDcConfigService {

    @Resource
    private DcConfigManager configManager;
    @Resource
    private DcConfigEntityManager configEntityManager;
    @Autowired
    private ApplicationContext applicationContext;


    /**
     * 新增配置
     * @param query
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertConfig(ConfigInsertQuery query) {
        //校验模板下类型是否已存在
        checkModuleType(query.getModuleId(),query.getType(),null);
        DcConfigEntity entity = Convert.convert(DcConfigEntity.class, query);
        boolean b = configManager.save(entity);
        if(b){
            List<DcConfigEntityEntity> list = createDefaultConfigEntity(entity.getId());
            configEntityManager.saveBatch(list);
        }
        return b;
    }

    /**
     * 修改配置
     * @param query
     * @return
     */
    @Override
    public boolean updateConfig(ConfigUpdateQuery query) {
        //校验模板下类型是否已存在
        checkModuleType(query.getModuleId(),query.getType(),query.getId());
        return configManager.updateById(Convert.convert(DcConfigEntity.class, query));
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public DcConfigEntity getConfigInfo(Long id) {
        return configManager.getById(id);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteConfig(Long id) {
        configManager.removeById(id);
        configEntityManager.removeByConfigId(id);
        return true;
    }

    @Override
    public PageInfo<DcConfigEntity> listConfig(ConfigListQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        return PageInfo.of(configManager.listConfig(query));
    }

    /**
     * 获取模块下的所有type
     * @param moduleId
     * @return
     */
    @Override
    public Set<String> getType(Long moduleId) {
        ConfigListQuery query = new ConfigListQuery();
        query.setModuleId(Collections.singletonList(moduleId));
        List<DcConfigEntity> list = configManager.listConfig(query);
        if(CollUtil.isEmpty(list)){
            return new HashSet<>();
        }
        return list.stream().map(DcConfigEntity::getType).collect(Collectors.toSet());
    }

    /**
     * 校验list接口
     * @param beanName
     */
    @Override
    public boolean checkList(ConfigCheckQuery query) {
        DcConfigService configService = getConfigService(query.getBeanName());
        try {
            List<? extends BaseConfigVO> list = configService.list(query.getParamMap());
            List<String> attrList = new ArrayList<>();
            if(null != query.getConfigId()){
                List<DcConfigEntityEntity> entityList = configEntityManager.listConfigEntity(query.getConfigId());
                if(CollUtil.isNotEmpty(entityList)){
                    attrList = entityList.stream().map(DcConfigEntityEntity::getAttribute).collect(Collectors.toList());
                }
            }
            return hasProperty(list, attrList);
        }catch (Exception e){
            log.error("测试list接口报错,{}",e);
            return false;
        }
    }

    @Override
    public boolean checkCount(ConfigCheckQuery query) {
        DcConfigService configService = getConfigService(query.getBeanName());
        try {
            configService.count(query.getParamMap());
            return true;
        }catch (Exception e){
            log.error("测试count接口报错,{}",e);
            return false;
        }
    }

    /**
     * 修改是否启用
     * @param query
     * @return
     */
    @Override
    public boolean updateEnable(ConfigUpdateEnableQuery query) {
        DcConfigEntity configInfo = getConfigInfo(query.getId());
        if(null == configInfo){
            return false;
        }
        configInfo.setIsEnable(query.getIsEnable());
        return configManager.updateById(configInfo);
    }

    /**
     * 获取所有待办模块id
     * @return
     */
    @Override
    public List<Long> allDcModule() {
        List<DcConfigEntity> list = configManager.list();
        if(CollUtil.isEmpty(list)){
            return new ArrayList<>();
        }
        return list.stream().map(DcConfigEntity::getModuleId).distinct().collect(Collectors.toList());
    }

    /**
     * 是否拥有属性
     * @param list
     * @param propertyName
     * @return
     */
    public boolean hasProperty(List<? extends BaseConfigVO> list, List<String> propertyNameList) {
        if (list == null || list.isEmpty() || propertyNameList.isEmpty()) {
            return false;
        }

        // 获取列表中的第一个对象的类
        Class<?> clazz = list.get(0).getClass();

        boolean result = true;
        try {
            for (String propertyName : propertyNameList) {
                // 尝试获取指定名称的字段
                Field field = getFieldRecursively(clazz,propertyName);
                // 如果字段存在，返回 true
                if(null == field){
                    result = false;
                    break;
                }
            }
            return result;

        } catch (Exception e) {
            // 如果字段不存在，捕获异常并返回 false
            return false;
        }
    }
    private Field getFieldRecursively(Class<?> clazz, String fieldName) {
        try {
            // 尝试获取当前类的字段
            return clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            // 如果当前类中没有找到字段，递归检查父类
            if (clazz.getSuperclass() != null) {
                return getFieldRecursively(clazz.getSuperclass(), fieldName);
            }
            // 如果父类也没有找到字段，返回 null
            return null;
        }
    }
    // ################################## 私有方法  ##################################

    public DcConfigService getConfigService(String beanName) {
        // 动态获取 Bean
        return getBean(beanName);
    }

    public  <T> T getBean(String beanName) {
        return (T) applicationContext.getBean(beanName);
    }

    /**
     * 校验code
     * @param code
     * @param id
     */
    private  void checkCode(String code,Long id){
        DcConfigEntity entity = configManager.getByCode(code);
        //新增
        if(null == id && entity != null){
            Asserts.fail("[module.code.exist]");
        }
        //编辑
        if(null != id && entity != null && !id.equals(entity.getId())){
            Asserts.fail("[module.code.exist]");
        }
    }

    /**
     * 校验模板下类型是否已存在
     * @param moduleId
     * @param type
     * @param id
     */
    private void checkModuleType(Long moduleId,String type,Long id){
        DcConfigEntity entity = configManager.getByModuleType(moduleId,type);
        //新增
        if(null == id && entity != null){
            Asserts.fail("[config.module.type.exist]");
        }
        //编辑
        if(null != id && entity != null && !id.equals(entity.getId())){
            Asserts.fail("[config.module.type.exist]");
        }
    }


    /**
     * 构建默认子项
     * @param configId
     * @return
     */
    private  List<DcConfigEntityEntity>  createDefaultConfigEntity(Long configId){
        List<DcConfigEntityEntity> list = new ArrayList<>();
        DcConfigEntityEntity entity  = new DcConfigEntityEntity();
        entity.setConfigId(configId);
        entity.setAttribute(ConfigConstant.DEFAULT_TITLE);
        entity.setTitle(ConfigConstant.DEFAULT_TITLE_NAME);
        entity.setIsShow(1);
        entity.setSort(1);
        //标题和创建时间 默认为 唯一值
        entity.setIsKey(1);
        entity.setIsQuery(1);
        entity.setIsSort(1);
        entity.setType(ConfigEntityTypeEnum.DEFAULT.getType());
        list.add(entity);

        DcConfigEntityEntity entity2 = BeanUtil.copyProperties(entity, DcConfigEntityEntity.class);
        entity2.setAttribute(ConfigConstant.DEFAULT_CREATE_TIME);
        entity.setTitle(ConfigConstant.DEFAULT_CREATE_TIME_NAME);
        entity2.setSort(2);
        list.add(entity2);
        return list;
    }
}
